package net.util;

import static org.lwjgl.opengl.GL11.glEnd;

import java.awt.Font;
import java.io.IOException;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Rectangle;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

@SuppressWarnings("unchecked")
public class GraphicsUtil 
{
	private GraphicsUtil()
	{
		
	}
	
	/**
	 * Returns the texture loaded from the image with path <code>fname</code> in the default image 
	 * file location. If an exception is thrown during loading the returned texture will be null.
	 * 
	 * If multiple instances require references to the same texture, it is recommended that said 
	 * texture be loaded <b>once</b> and stored a static variable, rather than creating multiple
	 * <code>Texture</code> instances of the same image.
	 * 
	 * @see FileUtil.IMAGE_FILE_PATH
	 * @param fname The file to load.
	 * @return The texture loaded from the file, or null if loading the texture failed.
	 * */
	public static Texture loadTexture(String fname)
	{
		Texture T;
		try
		{
			T = TextureLoader.getTexture("PNG", 
					ResourceLoader.getResourceAsStream(FileUtil.IMAGE_FILE_PATH + fname));
		}
		catch (IOException e)
		{
			e.printStackTrace();
			T = null;
		}
		
		return T;
	}
	
	/**
	 * Default drawing font. Plain style, size 12.
	 * */
	public static final UnicodeFont DEFAULT_FONT = new UnicodeFont(new Font("",Font.PLAIN,12));
	
	/**
	 * Renders a regular polygon of radius <code>r</code> centered around <code>x</code> and 
	 * <code>y</code> with <code>n</code> vertices. The first vertex will be to the right of
	 * the center.
	 * 
	 * @param x The x-coordinate of the polygon's center.
	 * @param y The y-coordinate of the polygon's center.
	 * @param n The number of vertices.
	 * @param r The radius of the polygon, measured from the center to the vertices.
	 * */
	public static void renderPolygon(double x, double y, int n, double r)
	{
		GL11.glBegin(GL11.GL_POLYGON);
		
		final double angle = Math.toRadians(360d/n);
		
		for (int i = 0; i <= n; i++)
		{
			GL11.glVertex2d(x + MathUtil.lx(r, i * angle), y + MathUtil.ly(r, i * angle));
		}
		
		glEnd();
	}

	public static void renderImage(Texture tex, double x, double y, double w, double h)
	{
		tex.bind();
		GL11.glBegin(GL11.GL_QUADS);
		
		GL11.glTexCoord2f(0, 0);
		GL11.glVertex2d(x, y);
		
		GL11.glTexCoord2f(1, 0);
		GL11.glVertex2d(x + w, y);
		
		GL11.glTexCoord2f(1, 1);
		GL11.glVertex2d(x + w, y + h);
		
		GL11.glTexCoord2f(0, 1);
		GL11.glVertex2d(x, y + h);
		
		GL11.glEnd();
	}
	
	public static void renderImage(Texture tex, Rectangle rect)
	{
		renderImage(tex, rect.getX(),rect.getY(),rect.getWidth(),rect.getHeight());
	}
	
	public static void renderImage(Texture tex, double x, double y)
	{
		renderImage(tex,x,y,tex.getTextureWidth(),tex.getTextureHeight());
	}
	
	/**
	 * Returns the modelview matric used by OpenGL.
	 * */
	public static float[][] getModelviewMatrix()
	{
		FloatBuffer F = BufferUtils.createFloatBuffer(16);
		
		GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, F);
	
		return new float[][]
		{
			{F.get(),F.get(),F.get(),F.get()},
			{F.get(),F.get(),F.get(),F.get()},
			{F.get(),F.get(),F.get(),F.get()},
			{F.get(),F.get(),F.get(),F.get()}
		};
	}

	static
	{
		DEFAULT_FONT.addAsciiGlyphs();
		DEFAULT_FONT.addGlyphs(400, 600);
		DEFAULT_FONT.getEffects().add(new ColorEffect(java.awt.Color.WHITE));
		try
		{
			DEFAULT_FONT.loadGlyphs();
		}
		catch (SlickException e)
		{
			e.printStackTrace();
		}
	}
}
